package com.vip.mvc.dispacher;

import com.vip.mvc.annotation.Autowired;
import com.vip.mvc.spring.NaBeansFactory;
import com.vip.mvc.utils.reflection.ClassReflection;
import com.vip.mvc.utils.reflection.ReflectionUtils;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by cloudy.xie on 17/2/21.
 */
public class RequestMap {
    private static org.slf4j.Logger logger = LoggerFactory.getLogger(RequestMap.class);
    private RequestMap() {
    }

    private static RequestMap instance = new RequestMap();

    public static RequestMap getInstance() {
        return instance;
    }

    //key requestUrl
    private Map<String, RequestParam> requestUrlMap = new HashMap<>();
    //key serviceName
    private Map<String, Object> serviceMap = new HashMap<>();

    public void initRequestMap() {
        initSeriver();//底层要先初始化

        Map<String, Object> controllerMap = NaBeansFactory.getControllerBeans();
        controllerMap.forEach((key,value)->{
            this.setFields(serviceMap,value);
            ClassReflection classReflection = ReflectionUtils.reflectionController(key,value);
            for (RequestParam requestMap : classReflection.getRequestMapList())
                requestUrlMap.put(requestMap.getUrl(), requestMap);
        });

    }

    private void initSeriver(){
        serviceMap = NaBeansFactory.getSerivceBeans();
        serviceMap.values().forEach(obj->setFields(serviceMap,obj));
    }

    public boolean checkIsExist(String requestUrl){
        if(!requestUrlMap.containsKey(requestUrl)){
            return false;
        }
        return true;
    }

    private void setFields(Map<String, Object> map,Object obj)  {
        Field[] fs = obj.getClass().getDeclaredFields();
        if(fs == null || fs.length<=0){
            return;
        }

        for (Field f:fs){
            if(f.isAnnotationPresent(Autowired.class)){
                f.setAccessible(true);
                String fieldName = f.getName();
                if(!map.containsKey(fieldName)){
                    logger.error("配置错误,类{}的属性{}需要配置注解",obj,fieldName);
                    throw new RuntimeException();
                }
                try {
                    f.set(obj,map.get(fieldName));
                } catch (IllegalAccessException e) {
                    logger.error("设置属性出错 ",e);
                }
            }
        }
    }

    public RequestParam getRequestParam(String requestUrl){
        return requestUrlMap.get(requestUrl);
    }
}
